package sketch.ast;

import java.util.List;

import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;

import sketch.util.Checker;
import sketch.util.SketchUtil;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class ASTCopyTest extends TestCase {
	
	public static Test suite() {
		return new TestSuite(ASTCopyTest.class);
	}
	
	private MethodDeclaration methodDeclaration;
	
	@Override
	public void setUp() {
		String filePath = "./testfiles/sketch/ast/TreeMapSketchExecutionForTest.java";
		CompilationUnit unit = ASTUtils.astRoot(filePath);
		List<AbstractTypeDeclaration> types = ASTUtils.typeDeclarations(unit);
		TypeDeclaration typeDeclaration = ASTUtils.getTypeDeclaration(types, "GenTest");
		MethodDeclaration methodDeclaration = ASTUtils.getMethodByName(typeDeclaration, "scratchTest");
		//check that scratchTest must exist
		Checker.checkNull(methodDeclaration, "There is no method called scratchTest");
		this.methodDeclaration = methodDeclaration;
	}
	
	public void testASTDeepCopy() {
		
		MethodDeclaration copy = (MethodDeclaration) methodDeclaration.copySubtree(methodDeclaration.getAST(), methodDeclaration);
		copy.getName().setIdentifier("changedMethodName");
		
		SketchUtil.stdln("The original copy: ");
		SketchUtil.stdln(methodDeclaration);
		
		SketchUtil.stdln("The copied version after minor changes: ");
		SketchUtil.stdln(copy);
	}
	
	public void testASTCopyUsingLibrary() {
		MethodDeclaration copy = ASTUtils.deepClone(this.methodDeclaration);
		copy.modifiers().remove(0);
		copy.getName().setIdentifier("removefirstmodifier");
		SketchUtil.stdln("The original copy: ");
		SketchUtil.stdln(methodDeclaration);
		
		SketchUtil.stdln("The copied version after deleting the first modifier and changing the name: ");
		SketchUtil.stdln(copy);
	}
	
	//show the internal property will never been changed
	public void testPositionAfterASTCopy() {
		MethodDeclaration copy = ASTUtils.deepClone(this.methodDeclaration);
		assertTrue(copy.getStartPosition() == this.methodDeclaration.getStartPosition());
		assertTrue(copy.getLength() == this.methodDeclaration.getLength());
		
		copy.modifiers().remove(0);
		assertTrue(copy.getStartPosition() == this.methodDeclaration.getStartPosition());
		assertTrue(copy.getLength() == this.methodDeclaration.getLength());
		
		copy.getName().setIdentifier("removefirstmodifier");
		assertTrue(this.methodDeclaration.getName().getStartPosition() == copy.getName().getStartPosition());
		assertTrue(this.methodDeclaration.getName().getLength() == copy.getName().getLength());
		SketchUtil.stdln("name length of copy: " + copy.getName().getLength());
	}
}
